package com.googlecode.lohr.parser.combinators.matcher.common;


import com.googlecode.lohr.parser.combinators.MatchError;
import com.googlecode.lohr.parser.combinators.matcher.MatchContext;
import com.googlecode.lohr.parser.combinators.matcher.Matcher;
import com.googlecode.lohr.parser.combinators.node.StringNode;

/**
 * Matches both single quoted or double quoted strings
 * 
 * @author Ted Stockwell
 */
public class QuotedStringMatcher
extends Matcher
{
	@Override
	public void match(MatchContext ctx, int start) 
	{
		final String input= ctx.getInput();
		if (input.length() <= start) {
			ctx.matchComplete(this, start, new MatchError("Unexpected end of input", start));
			return;
		}
			
		char startChar= input.charAt(start);
		if (startChar != '"' && startChar != '\'') {
			ctx.matchComplete(this, start, new MatchError("Excepted beginning of quote", start));
			return;
		}
		
		char escapeChar= (startChar == '"') ? '\'' : '"';
		int pos = input.indexOf(startChar, start+1);
		while (pos > 0 && input.charAt(pos - 1) == escapeChar)
			pos = input.indexOf(startChar, pos+1);

		if (pos == -1 || input.charAt(pos) != startChar) { 
			ctx.matchComplete(this, start, new MatchError("Excepted end of quote", input.length()));
			return;
		}
		pos++;

		String text= input.substring(start, pos).replaceAll(""+escapeChar+startChar, ""+startChar);
		StringNode node= new StringNode(this, start, pos, text);
		ctx.matchFound(this, start, node);
		ctx.matchComplete(this, start);
	}
	
	@Override
	public String getLabel()
	{
		return "quoted string";
	}

}
